package edu.rutgers.moko.data.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.http.HttpServletRequest;

import edu.rutgers.moko.data.FieldAccess;
import edu.rutgers.moko.data.ProtectedRule;

public class SecurityUtil {
	public static String getRemoteIp(HttpServletRequest req){
		return req.getRemoteAddr();
	}
	
	public static String getAccessPoint(){
		Runtime rt = Runtime.getRuntime();
		String MAC = null;
		Process proc;
		BufferedReader stdin;
		
		try {
			proc = rt.exec("iwconfig");
			stdin = new BufferedReader(new InputStreamReader(proc.getInputStream()));
			
			String line;
			while ((line = stdin.readLine()) != null) {
				if(line.contains("Access Point")){
					MAC = line.substring(line.indexOf("Access Point")+14);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return MAC;
	}

	public static boolean localAccess(HttpServletRequest req) {
		String ip = req.getRemoteAddr();
		if("127.0.0.1".equals(ip) || "192.168.0.202".equals(ip)){
			return true;
		}
		
		return false;
	}
	
	
	public static Boolean isVisible(String ip, FieldAccess fa){
		Boolean isVisible = false;
		switch (fa.getPrivacyMode()) {
		case PUBLIC:
			isVisible= true;
			break;

		case PRIVATE:
			if("127.0.0.1".equals(ip) || "192.168.0.202".equals(ip)){
				isVisible= true;
			}
			break;
		case PROTECTED:
			for (ProtectedRule rule : fa.getProtectedRules()) {
				switch (rule.getType()) {
				case LOCATION:
					//this method will need actual coordinates
					isVisible = testLocation(rule);
					break;
				case AP:
					isVisible = testAccessPoint(getAccessPoint(), rule);
					break;
				case CLIENT:
					isVisible = testClient(ip, rule);
					break;
				}
				
				if(isVisible){
					return true;
				}
			}
			break;
		}
		return isVisible;
	}

	private static Boolean testClient(String ip, ProtectedRule rule) {
		Boolean res = true;
		String client = getIpAsBiteSeq(ip);
		String sample = getIpAsBiteSeq(rule.getClientIp());
		String mask = getIpAsBiteSeq(rule.getSubnetMask());
		
		for (int i = 0; i <32 ; i++) {
			if(Integer.valueOf(mask.substring(i, i+1)) == 1){
				if(!sample.substring(i, i+1).equals(client.substring(i, i+1))){
					res = false;
					break;
				}
			}
			
		}
		
		if(!rule.getFlag().isVisible()){
			res = !res;
		}
		return res;
	}

	private static Boolean testAccessPoint(String mac, ProtectedRule rule) {
		Boolean res = false;
		if (mac != null) { // mac is null when server has no internet
			if (rule.getApId().toLowerCase().equals(mac.toLowerCase())) {
				res = true;
			}
			if (!rule.getFlag().isVisible()) {
				res = !res;
			}
		}
		return res;
	}

	private static Boolean testLocation(ProtectedRule rule) {
		return rule.getFlag().isVisible();
	}
	
	private static String getIpAsBiteSeq(String ip) {
		StringBuilder out = new StringBuilder();
		String[] ar = ip.replace(".",":").split(":");
		for (int i = 0; i < ar.length; i++) {
			int si = Integer.valueOf(ar[i]);
			String b = Integer.toBinaryString(si);
			while (b.length() < 8) {
				b = "0" + b;
			}
			out.append(b);
		}
		return out.toString();
	}

}
